/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package grayscale;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

/**
 *
 * @author WIN7
 */
public class MainPanel extends JPanel implements MouseListener{
        
    private BufferedImage background_image, background_gray_image;
    private boolean is_showing_gray;
    public MainPanel(){
        
    }
    public void Initialize(){
        addMouseListener(this);
        File image_file = new File("res/paint.jpg");
        try{
            background_image = ImageIO.read(image_file);
        }catch(IOException e){
        }

        is_showing_gray = false;
        background_gray_image = MakeGrayImage(background_image, background_image.getWidth(), background_image.getHeight());
        
    }
    
    
    @Override
    public void paintComponent(Graphics g){
        g.clearRect(0, 0, getWidth(), getHeight());
        if(!is_showing_gray)
            g.drawImage(background_image, 0, 0, this);
        else
            g.drawImage(background_gray_image, 0, 0, this);
    }


    private BufferedImage MakeGrayImage(BufferedImage src_image, int new_image_width, int new_image_height){
        int[][] color_array = BufferedImage_To_2DArray(src_image, new_image_width, new_image_height);
        color_array = RGB_To_Gray_Array(color_array, new_image_width, new_image_height);
        return Array2D_To_BufferedImage(color_array, src_image.getWidth(null), src_image.getHeight(null));
    }

    private int[][] RGB_To_Gray_Array(int[][] rgb_array, int new_image_width, int new_image_height){
        int[][] gray_array = new int[new_image_width][new_image_height];
        int red_fillter_number = Integer.parseInt("00ff0000", 16);
        int green_fillter_number = Integer.parseInt("0000ff00", 16);
        int blue_fillter_number = Integer.parseInt("000000ff", 16);        
        int current_pixel_red_value = 0;
        int current_pixel_green_value = 0;
        int current_pixel_blue_value = 0;
        int current_pixel_gray_value = 0;
        for(int i = 0; i < new_image_width; i ++){
            for(int j = 0; j < new_image_height; j ++){
                current_pixel_red_value = ((rgb_array[i][j]&red_fillter_number)>>16);    
                current_pixel_green_value = ((rgb_array[i][j]&green_fillter_number)>>8);      
                current_pixel_blue_value = (rgb_array[i][j]&blue_fillter_number);        
                current_pixel_gray_value = (current_pixel_red_value + current_pixel_green_value + current_pixel_blue_value)/3;          
                gray_array[i][j] = blue_fillter_number;   
                gray_array[i][j] = (gray_array[i][j] << 8);          
                gray_array[i][j] = (gray_array[i][j]|current_pixel_gray_value);  
                gray_array[i][j] = (gray_array[i][j] << 8);
                gray_array[i][j] = (gray_array[i][j]|current_pixel_gray_value);              
                gray_array[i][j] = (gray_array[i][j] << 8);
                gray_array[i][j] = (gray_array[i][j]|current_pixel_gray_value);          
            }
        }
        return gray_array;
    }
    
    private BufferedImage Array2D_To_BufferedImage(int[][] src_array, int new_image_width, int new_image_height){
        BufferedImage bufferedimage = new BufferedImage(new_image_width, new_image_height, BufferedImage.TYPE_INT_ARGB);
        for(int i = 0; i < new_image_width; i ++){
            for(int j = 0; j < new_image_height; j ++){
                 bufferedimage.setRGB(i, j, src_array[i][j]);
            }
        }
        return bufferedimage;        
    }

    private int[][] BufferedImage_To_2DArray(BufferedImage src_image, int new_image_width, int new_image_height){
        int[][] color_array = new int[new_image_width][new_image_height];
        for(int i = 0; i < new_image_width; i ++){
            for(int j = 0; j < new_image_height; j ++){
                color_array[i][j] = src_image.getRGB(i, j);
            }
        }
        return color_array;
    }

    private Image BufferedImage_To_Image(BufferedImage src_image){
        Image image = getToolkit().createImage(src_image.getSource());
        return image;
    }

    private BufferedImage Image_To_BufferedImage(Image src_image, int width, int height){
        //@TODO: Implement this method
        return null;
    }


    private BufferedImage RotateBufferedImage(BufferedImage src_image, boolean clockwise){
        int[][] image_data = BufferedImage_To_2DArray(src_image, src_image.getWidth(), src_image.getHeight());
        image_data = Rotate_2D_Int_Array(image_data, clockwise);        
        return Array2D_To_BufferedImage(image_data, src_image.getHeight(), src_image.getWidth());
    }

    private int[][] Rotate_2D_Int_Array(int[][] array, boolean is_clockwise){
        int array_row_num = array.length;
        int array_col_num = array[0].length;
        int[][] tmp_array = new int[array_col_num][array_row_num];
        for(int i = 0; i < array_row_num; i ++){
            for(int j = 0; j < array_col_num; j ++){
                if(is_clockwise)
                    tmp_array[j][array_row_num - 1 - i] = array[i][j];
                else
                    tmp_array[array_col_num - 1 - j][i] = array[i][j];
            }
        }
        return tmp_array;
    }

    public void mouseClicked(MouseEvent e) {
        if(e.getButton() == MouseEvent.BUTTON1){
            background_image = RotateBufferedImage(background_image, true);
        }else if(e.getButton() == MouseEvent.BUTTON2){
            is_showing_gray = !is_showing_gray;
        }else{
            background_image = RotateBufferedImage(background_image, false);
        }        
        background_gray_image = MakeGrayImage(background_image, background_image.getWidth(), background_image.getHeight());
        repaint();
    }

    public void mousePressed(MouseEvent e) {

    }

    public void mouseReleased(MouseEvent e) {

    }

    public void mouseEntered(MouseEvent e) {

    }

    public void mouseExited(MouseEvent e) {

    }

}
